package com.custom.action.core.plugin;

import com.custom.action.core.methods.MethodKind;
import com.custom.comm.utils.CustomApp;

import java.util.*;

/**
 * @author XiaoBai
 * @since 2024/1/17 14:50
 */
public class InterceptHandler {

    private final ExecuteInterceptor interceptor;

    private final Set<MethodKind> includeKindSet;

    private final Set<MethodKind> excludeKindSet;

    public InterceptHandler() {
        this.interceptor = createInterceptor();
        this.includeKindSet = new HashSet<>();
        this.excludeKindSet = new HashSet<>();
        if (interceptor != null) {
            Intercepts intercepts = interceptor.getClass().getAnnotation(Intercepts.class);
            if (intercepts != null) {
                includeKindSet.addAll(Arrays.asList(intercepts.include()));
                excludeKindSet.addAll(Arrays.asList(intercepts.exclude()));
            }
        }
    }

    private boolean isAvailable() {
        return interceptor != null;
    }

    private boolean hitTarget(MethodKind kind) {
        if (includeKindSet.isEmpty()) {
            return !excludeKindSet.contains(kind);
        }
        return includeKindSet.contains(kind) && !excludeKindSet.contains(kind);
    }

    private static ExecuteInterceptor createInterceptor() {
        ExecuteInterceptor interceptor;
        try {
            interceptor = CustomApp.getBean(ExecuteInterceptor.class);
        }catch (Exception e) {
            interceptor = null;
        }
        return interceptor;
    }

    public Object proceed(Invocation invocation, MethodKind kind) throws Exception {
        if (isAvailable() && hitTarget(kind)) {
            return interceptor.intercept(invocation);
        }
        return invocation.proceed();
    }


}


